package com.gzc.just.play.last.war.sceneserver.gameobject.base;

/**
 * 三维向量类 - 表示方向和大小
 * 
 * @author AI Assistant
 * @version 1.0.0
 * @since 2025-11-22
 */
public class Vector3 {
    private float x;  // X分量
    private float y;  // Y分量
    private float z;  // Z分量
    
    // 常用的向量常数
    public static final Vector3 ZERO = new Vector3(0, 0, 0);
    public static final Vector3 ONE = new Vector3(1, 1, 1);
    public static final Vector3 UP = new Vector3(0, 1, 0);
    public static final Vector3 DOWN = new Vector3(0, -1, 0);
    public static final Vector3 RIGHT = new Vector3(1, 0, 0);
    public static final Vector3 LEFT = new Vector3(-1, 0, 0);
    public static final Vector3 FORWARD = new Vector3(0, 0, 1);
    public static final Vector3 BACKWARD = new Vector3(0, 0, -1);

    /**
     * 构造函数
     */
    public Vector3() {
        this.x = 0;
        this.y = 0;
        this.z = 0;
    }
    
    /**
     * 带参数的构造函数
     */
    public Vector3(float x, float y, float z) {
        this.x = x;
        this.y = y;
        this.z = z;
    }
    
    // Getter和Setter方法
    public float getX() {
        return x;
    }
    
    public void setX(float x) {
        this.x = x;
    }
    
    public float getY() {
        return y;
    }
    
    public void setY(float y) {
        this.y = y;
    }
    
    public float getZ() {
        return z;
    }
    
    public void setZ(float z) {
        this.z = z;
    }
    
    /**
     * 获取向量的长度（模）
     */
    public float length() {
        return (float) Math.sqrt(x * x + y * y + z * z);
    }
    
    /**
     * 规范化向量（单位向量）
     */
    public Vector3 normalize() {
        float len = length();
        if (len == 0) {
            return new Vector3(0, 0, 0);
        }
        return new Vector3(x / len, y / len, z / len);
    }
    
    /**
     * 向量点积
     */
    public float dot(Vector3 other) {
        if (other == null) {
            return 0;
        }
        return x * other.x + y * other.y + z * other.z;
    }
    
    /**
     * 向量叉积
     */
    public Vector3 cross(Vector3 other) {
        if (other == null) {
            return new Vector3(0, 0, 0);
        }
        return new Vector3(
                y * other.z - z * other.y,
                z * other.x - x * other.z,
                x * other.y - y * other.x
        );
    }
    
    /**
     * 向量加法
     */
    public Vector3 add(Vector3 other) {
        if (other == null) {
            return new Vector3(x, y, z);
        }
        return new Vector3(x + other.x, y + other.y, z + other.z);
    }
    
    /**
     * 向量减法
     */
    public Vector3 subtract(Vector3 other) {
        if (other == null) {
            return new Vector3(x, y, z);
        }
        return new Vector3(x - other.x, y - other.y, z - other.z);
    }
    
    /**
     * 向量缩放
     */
    public Vector3 scale(float scalar) {
        return new Vector3(x * scalar, y * scalar, z * scalar);
    }
    
    /**
     * 向量乘法（别名）
     */
    public Vector3 multiply(float scalar) {
        return scale(scalar);
    }
    
    /**
     * 向量乘法（别名）
     */
    public Vector3 multiply(double scalar) {
        return scale((float) scalar);
    }
    
    /**
     * 计算与另一个向量的夹角（弧度）
     */
    public float angleTo(Vector3 other) {
        if (other == null) {
            return 0;
        }
        float len1 = length();
        float len2 = other.length();
        if (len1 == 0 || len2 == 0) {
            return 0;
        }
        float cosAngle = dot(other) / (len1 * len2);
        // 确保值在 [-1, 1] 范围内
        cosAngle = Math.max(-1, Math.min(1, cosAngle));
        return (float) Math.acos(cosAngle);
    }

    @Override
    public String toString() {
        return String.format("Vector3{x=%.2f, y=%.2f, z=%.2f}", x, y, z);
    }
}